﻿using System;
using System.Collections.Generic;
using System.Collections;

namespace AAA.Base.Util.SafeCollection
{
	public class ThreadSafeList<T>
	{
		private List<T> _lstSource = new List<T>();
		private T _tMax = default(T);
		private T _tMin = default(T);

        public void AddRange(IEnumerable<T> enumData)
        {
            foreach (T tData in enumData)
                Add(tData);
        }

		public void Add(T item)
		{
			Insert(-1, item);
		}

		public void Insert(int iIndex, T item)
		{
			lock (((ICollection)_lstSource).SyncRoot)
			{
				if(iIndex < 0)
					_lstSource.Add(item);
				else
					_lstSource.Insert(iIndex, item);
				
				if(item is IComparable)
					_tMax = (_tMax == null)
                            ?   item
                            :   (_tMax.Equals(default(T)))
								?	item
								: ((IComparable)item).CompareTo((IComparable)_tMax) > 0
									?	item
									:	_tMax;

				if (item is IComparable)
					_tMin = (_tMin == null)
                            ?   item
                            :   (_tMin.Equals(default(T)))
								? item
								: ((IComparable)item).CompareTo((IComparable)_tMin) < 0
									? item
									: _tMin;
			}
		}

		public int IndexOf(T item)
		{
			return _lstSource.IndexOf(item);
		}

		public void RemoveAt(int iIndex)
		{
			try
			{
				Remove(_lstSource[iIndex]);
			}
			catch (Exception ex)
			{
				
			}
		}

		public void Remove(T item)
		{
			lock (((ICollection)_lstSource).SyncRoot)
			{
				_lstSource.Remove(item);

				if (item.Equals(_tMax) && _lstSource.Count > 0)
				{
					_tMax = _lstSource[0];
					foreach (T sourceItem in _lstSource)
						_tMin = ((IComparable)sourceItem).CompareTo((IComparable)_tMax) > 0
									? sourceItem
									: _tMax;
				}

				if (item.Equals(_tMin) && _lstSource.Count > 0)
				{
					_tMin = _lstSource[0];
					foreach(T sourceItem in _lstSource)
						_tMin = ((IComparable)sourceItem).CompareTo((IComparable)_tMin) < 0
									? sourceItem
									: _tMin;
				}


			}
		}

		public T Max()
		{
			return _tMax;
		}

		public T Min()
		{
			return _tMin;
		}

		public int Count
		{
			get { return _lstSource.Count; }
		}

		public T this[int index]
		{
			get { return _lstSource[index];}
			set { _lstSource[index] = value; }
		}
	}
}
